<template>
  <div class="ant-image-preview-root" v-if="state.visible">
    <div
      class="fixed top-10px left-10px ant-tag-green ant-tag z-99999"
      v-if="state.tag"
    >
      {{ state.tag }}
    </div>
    <div class="ant-image-preview-mask"></div>
    <div tabindex="-1" class="ant-image-preview-wrap" role="dialog">
      <div role="document" class="ant-image-preview">
        <div
          tabindex="0"
          aria-hidden="true"
          style="width: 0px; height: 0px; overflow: hidden"
        ></div>
        <div class="ant-image-preview-content">
          <!----><!---->
          <div class="ant-image-preview-body">
            <ul class="ant-image-preview-operations">
              <li class="ant-image-preview-operations-operation" @click="close">
                <CloseOutlined class="ant-image-preview-operations-icon" />
              </li>
              <li
                v-if="!isDisabledAction"
                class="ant-image-preview-operations-operation"
                @click="zoomIn"
              >
                <ZoomInOutlined class="ant-image-preview-operations-icon" />
              </li>
              <li
                v-if="!isDisabledAction"
                @click="zoomOut"
                :class="{
                  'ant-image-preview-operations-operation-disabled':
                    state.zoomIndex === 1
                }"
                class="ant-image-preview-operations-operation"
              >
                <ZoomOutOutlined class="ant-image-preview-operations-icon" />
              </li>
              <li
                v-if="!isDisabledAction"
                class="ant-image-preview-operations-operation"
                @click="rotateRight"
              >
                <RotateRightOutlined
                  class="ant-image-preview-operations-icon"
                />
              </li>
              <li
                v-if="!isDisabledAction"
                class="ant-image-preview-operations-operation"
                @click="rotateLeft"
              >
                <RotateLeftOutlined class="ant-image-preview-operations-icon" />
              </li>
            </ul>
            <video-player
              ref="videoRef"
              v-if="state.src && isVideo(state.src)"
              controls
              style="
                pointer-events: auto;
                width: 80%;
                height: 80%;
                transform: translate(10%, 10%);
              "
              :src="state.src"
            ></video-player>
            <div
              v-else
              class="ant-image-preview-img-wrapper"
              style="transform: translate3d(0px, 0px, 0px)"
            >
              <img
                v-show="state.spinnig"
                :src="state.loadingImg"
                class="loading"
                alt=""
                srcset=""
              />
              <img
                v-show="!state.spinnig"
                v-drag
                loading="lazy"
                :src="state.src"
                class="ant-image-preview-img"
                :style="{
                  transform: imgStyle
                }"
              />
            </div>
            <div
              class="ant-image-preview-switch-left"
              :class="{
                'ant-image-preview-switch-left-disabled':
                  state.activeIndex === 0
              }"
              @click="prev"
            >
              <LeftCircleOutlined />
            </div>
            <div
              class="ant-image-preview-switch-right"
              @click="next"
              :class="{
                'ant-image-preview-switch-left-disabled':
                  state.activeIndex === state.previewImages.length - 1
              }"
            >
              <RightCircleOutlined />
            </div>
          </div>
          <!---->
        </div>
        <div
          tabindex="0"
          aria-hidden="true"
          style="width: 0px; height: 0px; overflow: hidden"
        ></div>
      </div>
    </div>
    <span
      class="fs12 fixed bottom-5px left-1/2 z-99999 text-white bg-black px-11px py-1px bg-opacity-40 rounded-3xl ml-[-24px]"
      >{{ state.activeIndex + 1 }}/{{ state.previewImages.length }}</span
    >
  </div>
</template>
<script setup>
import {
  ZoomOutOutlined,
  ZoomInOutlined,
  CloseOutlined,
  RotateRightOutlined,
  RotateLeftOutlined,
  LeftCircleOutlined,
  RightCircleOutlined
} from '@ant-design/icons-vue'
import {
  computed,
  watch,
  reactive,
  nextTick,
  defineAsyncComponent,
  ref
} from 'vue'
import loadingImg from '@/assets/img/loading.gif'
import VideoPlayer from './business/VideoPlayer.vue'
import { handerImageURL } from 'utils/file.js'
import { isVideo } from 'utils/utils'

const errorImg = defineAsyncComponent(
  () => import('@/assets/img/img-error.png')
)
const props = defineProps({
  close: {
    type: Function
  },
  visible: {
    type: Boolean,
    default: false
  },
  listSrc: {
    type: Array,
    default: () => []
  },
  src: {
    type: String,
    default: ''
  },
  previewCompress: {
    type: Boolean,
    default: true
  },
  tag: {
    type: String,
    default: ''
  },
  tagList: {
    type: Array,
    default: () => []
  }
})
const emit = defineEmits(['update:visible'])
const videoRef = ref(null)
const state = reactive({
  previewImages: props.listSrc.length ? props.listSrc : [props.src],
  previewTags: props.tagList.length ? props.tagList : [props.tag],
  zoomIndex: 1,
  rotate: 0,
  spinnig: false,
  src: '',
  loadingImg: `${loadingImg}`,
  visible: props.visible,
  activeIndex: 0,
  videoRef,
  tag: ''
})

state.activeIndex = state.previewImages?.findIndex(item => item === props.src)

/**
 * 图片样式
 */
const imgStyle = computed(() => {
  const { zoomIndex, rotate } = state
  return `scale3d(${zoomIndex}, ${zoomIndex}, 1) rotate(${rotate}deg)`
})

const isDisabledAction = computed(() => {
  return isVideo(state.src)
})

// 下一页
const next = () => {
  if (state.activeIndex < state.previewImages.length - 1) {
    state.activeIndex++
    setImgLink()
  }
}
// 前一页
const prev = () => {
  if (state.activeIndex > 0) {
    state.activeIndex--
    setImgLink()
  }
}
// 加载图片
const setImgLink = () => {
  state.rotate = 0
  state.zoomIndex = 1
  loadImg()
}
/**
 * 加载图片
 */
const loadImg = () => {
  state.spinnig = true
  const src = state.previewImages[state.activeIndex]
  const tag = state.previewTags[state.activeIndex]
  state.tag = tag
  if (isVideo(src)) {
    state.src = src
    nextTick(() => {
      videoRef.value?.pause()
    })
  } else {
    const img = new Image()

    img.onload = function () {
      state.src = props.previewCompress
        ? handerImageURL(src, {
            w: 800
          })
        : src
      nextTick(() => {
        state.spinnig = false
      })
    }
    img.onerror = function () {
      state.src = errorImg
      nextTick(() => {
        state.spinnig = false
      })
    }
    img.src = src
  }
}

// 放大
const zoomIn = () => {
  state.zoomIndex++
}

// 缩小
const zoomOut = () => {
  if (state.zoomIndex > 1) {
    state.zoomIndex--
  }
}

// 旋转
const rotateRight = () => {
  state.rotate += 90
}

const rotateLeft = () => {
  state.rotate -= 90
}

// 关闭弹框
const close = () => {
  props.close ? props.close() : emit('update:visible', false)
}

const vDrag = {
  beforeMount: el => {
    // 在元素上做些操作
    el.onmousedown = function (e) {
      e.preventDefault()
      e.stopPropagation()
      // const nodeName = e.currentTarget.nodeName
      const disx = e.clientX - el.offsetLeft
      const disy = e.clientY - el.offsetTop

      document.onmousemove = function (e) {
        let x = e.clientX - disx
        const y = e.clientY - disy
        if (x >= window.innerWidth - el.offsetWidth) {
          x = window.innerWidth - el.offsetWidth
        }
        el.parentElement.style.transform = `translate3d(${x}px,${y}px,0px)`
      }
      document.onmouseup = function () {
        // el.parentElement.style.transform = `translate3d(0px,0px,0px)`
        document.onmousemove = document.onmouseup = null
      }
    }
  }
}

watch(
  () => props.visible,
  val => {
    state.visible = val
  }
)
setImgLink()
</script>
<style lang="scss" scoped>
.ant-image-preview-img-wrapper .loading {
  width: 100px;
  height: 100px;
}
</style>
